package com.ruoyi.system.biz.impl;

import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.biz.WarehouseService;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.request.DeliveryOrderAdd;
import com.ruoyi.system.request.WarehousingEntryAdd;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Service
public class WarehouseServiceImpl implements WarehouseService {
    @Autowired
    private IWarehousingEntryInfoService warehousingEntryInfoService;
    @Autowired
    private IMaterialInventoryService materialInventoryService;
    @Autowired
    private IMaterialInfoService materialInfoService;
    @Autowired
    private IWarehousingEntryService warehousingEntryService;
    @Autowired
    private IDeliveryOrderService deliveryOrderService;
    @Autowired
    private IOutboundInfoService outboundInfoService;
    @Autowired
    private IDeliveryOrderInfoService deliveryOrderInfoService;

    /**
     * 新增入库单
     *
     * @param warehousingEntry 入库单
     * @return 结果
     */
    @Override
    @Transactional
    public int warehousingEntry(WarehousingEntryAdd warehousingEntry) {
        List<WarehousingEntryInfo> goods = warehousingEntry.getGoods();
        if (CollectionUtils.isEmpty(goods)) {
            throw new BaseException("新增入库单", "新增入库单失败，物料信息不能为空");
        }
        List<MaterialInventory> list = new ArrayList<>();

        for (WarehousingEntryInfo entryInfo : goods) {
            entryInfo.setSupplierId(warehousingEntry.getSupplierId());
            entryInfo.setEntryOrderId(warehousingEntry.getEntryOrderId());
            MaterialInventory materialInventory = new MaterialInventory();
            BeanUtils.copyBeanProp(materialInventory, entryInfo);

            if (entryInfo.getEntryNum() <= 0) {
                throw new BaseException("物料入库", "入库物料数不能小于0");
            }
            materialInfoService.updateMaterial(entryInfo.getMaterialId(), true, entryInfo.getEntryNum());
            list.add(materialInventory);
        }
        warehousingEntryInfoService.saveBatch(goods);
        materialInventoryService.saveBatch(list);

        return warehousingEntryService.insertWarehousingEntry(warehousingEntry);
    }

    @Override
    @Transactional
    public int addDeliveryOrder(DeliveryOrderAdd deliveryOrder) {
        List<DeliveryOrderInfo> goods = deliveryOrder.getGoods();
        if (CollectionUtils.isEmpty(goods)) {
            throw new BaseException("新增出库单", "新增出库单失败，物料信息不能为空");
        }
        List<OutboundInfo> outboundInfos = new ArrayList<>();
        for (DeliveryOrderInfo good : goods) {
            good.setOrderId(deliveryOrder.getOrderId());
            // 实际需要扣除的库存
            Integer actualOutboundNum = good.getActualOutboundNum();
            String materialId = good.getMaterialId();
            materialInfoService.updateMaterial(materialId, false, actualOutboundNum);

            List<MaterialInventory> materialInventories = materialInventoryService.selectByMaterialId(materialId, good.getSupplierId());
            if (CollectionUtils.isEmpty(materialInventories)) {
                throw new BaseException("新增出库单", "新增出库单失败，物料库存不足物料编号：" + materialId + "需要：" + actualOutboundNum + "剩余库存：" + "0");
            }
            int totalCount = materialInventories.stream().mapToInt(MaterialInventory::getEntryNum).sum();
            if (totalCount < actualOutboundNum) {
                throw new BaseException("新增出库单", "新增出库单失败，物料库存不足物料编号：" + materialId + "需要：" + actualOutboundNum + "剩余库存：" + totalCount);
            }

            int leftNum = actualOutboundNum;
            // 计算实际出库
            for (MaterialInventory materialInventory : materialInventories) {
                int entryNum = materialInventory.getEntryNum();
                if (entryNum <= 0) {
                    continue;
                }

                OutboundInfo outboundInfo = new OutboundInfo();
                outboundInfo.setOrderId(deliveryOrder.getOrderId());
                outboundInfo.setMaterialId(materialInventory.getMaterialId());
                outboundInfo.setUnitPrice(materialInventory.getUnitPrice());
                outboundInfo.setBrand(materialInventory.getBrand());
                outboundInfo.setProducer(materialInventory.getProducer());
                outboundInfo.setSupplierId(materialInventory.getSupplierId());
                outboundInfos.add(outboundInfo);

                int ln = Math.abs(leftNum);
                leftNum = entryNum - ln;
                if (leftNum >= 0) {
                    outboundInfo.setQuantity(ln);
                    materialInventory.setEntryNum(leftNum);
                    // 更新库存表
                    materialInventoryService.updateById(materialInventory);
                    break;
                }
                outboundInfo.setQuantity(materialInventory.getEntryNum());
                materialInventory.setEntryNum(0);

                // 更新库存表
                materialInventoryService.updateById(materialInventory);
            }
        }
        // 添加出库单详情
        deliveryOrderInfoService.saveBatch(goods);
        // 添加出库物料记录
        outboundInfoService.saveBatch(outboundInfos);
        // 添加出库单
        return deliveryOrderService.insertDeliveryOrder(deliveryOrder);
    }

}
